package Dao;

import java.sql.*;
import java.util.ArrayList;


/**
 * 封装了两个方法，一类是带返回值的（插入、删除、更改），另一类是带返回的（select）
 * @param <T> 泛型对象，在这个项目里有StudentCourse和Sting两种对象
 */
public abstract class BaseDao<T> {
    /**
     * 实体方法，不带返回值 应用于插入、删除、变更数据
     * @param sql 外部传进来的sql语句
     * @param Object 泛型对象
     * @author 张潇川
     */
     public void alter(String sql, T Object) {

        Connection connection = DBconnection.getConn();
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            insert(preparedStatement,Object);//这里调用抽象方法，具体的实现方法在子类中
            preparedStatement.execute();
            preparedStatement.close();
            connection.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 带返回值，应用于查找操作
     * @param sql
     * @param Object
     * @return 返回的是一个ArrayList
     * @author 张潇川
     */
    public ArrayList<T> select(String sql,T Object) {
        ArrayList<T> courses = new ArrayList<>();
        Connection connection = DBconnection.getConn();
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            insert(preparedStatement,Object);

            //用ResultSetMetaData获取有多少列，因为课程需要添加删除，所以列数不固定
            ResultSetMetaData resultSetMetaData = preparedStatement.getMetaData();
            int count = resultSetMetaData.getColumnCount();

            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                courses.add(setObjectByResultSet(resultSet,count));
            }
            preparedStatement.close();
            connection.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return courses;
    }
    public abstract void insert(PreparedStatement preparedStatement,T Object);

    public abstract T setObjectByResultSet(ResultSet resultSet,int count);
}
